package com.xbdnote.java8.study;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.xbdnote.java8.study.service.XbdService;
import com.xbdnote.java8.study.service.bo.XbdBo;
import com.xbdnote.java8.study.service.impl.XbdServiceImpl;

/**
 * @Author 小白丁
 * @Date 2021/11/20 22:12
 * @Version 1.0
 * @Description 针对六种典型的空指针进行学习
 * 包装类型的空指针问题
 * 级联调用的空指针问题
 * Equals方法左边的空指针问题
 * ConcurrentHashMap 这样的容器不支持 Key 和 Value 为 null。
 * 集合，数组直接获取元素
 * 对象直接获取属性
 */
public class NullPointExceptionStudy {
    /**
     * 1、包装类型的空指针问题
     * eg:在使用过程中，参数i可能因为程序异常或者调用人员不仔细而传入null，导致NPE
     *
     * @param i 参数
     * @return
     */
    public static Integer packageNpe(Integer i) {
        return i + 1;
    }

    /**
     * 2、级联调用的空指针问题
     * 因业务场景复杂，出现级联调用时，未判断空
     */
    public static Boolean cascadeNpe() {
        XbdService xbdService = new XbdServiceImpl();
        //查看BO是否时小白丁,xbdService.getBo()方法可能返回了null
        boolean result = xbdService.getBo()
            .getName()
            .equals("小白丁学习笔记");
        //亦或是这么写，但是还是逃脱不了xbdService.getBo()方法可能返回了null的命运
        result = "小白丁学习笔记".equals(xbdService.getBo()
            .getName());
        return result;

    }

    /**
     * 3、Equals方法左边的空指针问题
     * 其实看了第二个实例，也就不难发现，我们其实很多时候可能遇到的问题就是equals出现NPE
     *
     * @return
     */
    public static void EqualsNpe() {
        //返回名字是否是：小白丁学习笔记
        String temp = null;
        //当temp字段未空的时候，系统就可能出现NPE
        if (temp.equals("小白丁学习笔记")) {
            System.out.println("小白丁学习笔记进来了");
        }
    }

    /**
     * 4、ConcurrentHashMap 这样的容器不支持 Key 或者 Value 为 null。
     * 在concurrentHashMap 的put中，第一行就提示了K/V任何一个都不能是null：if (key == null || value == null) throw new NullPointerException();
     */
    public static void concurrentMapNpe() {
        Map map = new ConcurrentHashMap();
        String key = null;
        String value = null;
        //在put进入的时候，一定要先判断非空
        map.put(key, value);
    }

    /**
     * 5、集合，数组直接获取元素
     */
    public static void collectNpe() {
        int[] array = null;
        List<Integer> list = null;
        //以下两个方法都会提示空指针异常
        System.out.println(array[0]);
        System.out.println(list.get(0));
    }

    /**
     * 6、对象直接获取属性
     */
    public static String objNpe() {
        XbdBo xbd = null;
        //未判断对象状态，直接获取，空指针异常
        return xbd.getName();
    }

    public static void main(String[] args) {
        collectNpe();
    }
}
